package com.grm.sys.service;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.grm.security.details.LoginUser;
import com.grm.sys.entity.LoginUserInfo;
import com.grm.sys.entity.SysMenu;
import com.grm.util.RedisUtil;
import com.grm.util.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 首页逻辑(获取登录用户信息和用户所拥有的菜单信息)
 *
 * @author gaorimao
 * @date 2022/02/11
 */
@Service
public class HomeService {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private SecurityUtils securityUtils;
    @Autowired
    private SysMenuService sysMenuService;

    public LoginUserInfo getHome() {
        // 1. 获取当前登录用户
        LoginUser loginUser = securityUtils.getLoginUser();

        LoginUserInfo loginUserInfo;
        // 从缓存中获取当前登录用户信息
        Object loginUserInfoObj = redisUtil.get("LoginUserInfo:" + loginUser.getUsername());
        if (!ObjectUtils.isEmpty(loginUserInfoObj)) {
            // 从缓存中拿
            loginUserInfo = (LoginUserInfo) loginUserInfoObj;
        } else {
            // 从DB中拿
            loginUserInfo = queryLoginUserInfoByDb(loginUser);
            // 存入缓存一份
            redisUtil.set("LoginUserInfo:" + loginUser.getUsername(), loginUserInfo, 60 * 60 * 24 * 7);
        }
        return loginUserInfo;
    }

    /**
     * 从数据库查询登录用户信息
     *
     * @param loginUser 登录用户
     * @return {@link LoginUserInfo}
     */
    private LoginUserInfo queryLoginUserInfoByDb(LoginUser loginUser) {
        // 1.获取用户头像
        String avatar = loginUser.getAvatar();
        List<SysMenu> allMenus = getSysMenusByUserId(loginUser.getUserId());
        // 2. 只查用户的目录和菜单
        List<SysMenu> sysMenus = Optional.ofNullable(allMenus).orElse(new ArrayList<>()).stream().filter(x -> (x.getType() != 2)).collect(Collectors.toList());
        List<SysMenu> sysMenuTree = sysMenuService.buildTree(sysMenus);
        // 3.获取用户路由权限
        List<String> routers = Optional.ofNullable(allMenus).orElse(new ArrayList<>()).stream()
                .map(SysMenu::getPath)
                .filter(ObjectUtils::isNotEmpty).collect(Collectors.toList());
        // 4. 获取用户按钮权限
        List<String> perms = Optional.ofNullable(allMenus).orElse(new ArrayList<>()).stream()
                .map(SysMenu::getPerms)
                .filter(ObjectUtils::isNotEmpty).collect(Collectors.toList());
        List<String> paths = Optional.ofNullable(allMenus).orElse(new ArrayList<>()).stream()
                .map(SysMenu::getPath)
                .filter(ObjectUtils::isNotEmpty).collect(Collectors.toList());
        perms.addAll(paths);
        LoginUserInfo loginUserInfo = new LoginUserInfo();
        loginUserInfo.setUsername(loginUser.getUsername());
        loginUserInfo.setAvatar(avatar);
        loginUserInfo.setSysMenus(sysMenuTree);
        loginUserInfo.setRouters(routers);
        loginUserInfo.setPerms(perms);
        return loginUserInfo;
    }

    /**
     * 通过用户id获取系统菜单
     *
     * @param userId 登录用户id
     * @return {@link List}<{@link SysMenu}>
     */
    private List<SysMenu> getSysMenusByUserId(Long userId) {
        List<SysMenu> sysMenus;
        if (securityUtils.isAdmin(userId)) {
            // 查所有目录和菜单
            sysMenus = sysMenuService.queryMenusByUserId(null);
        } else {
            sysMenus = sysMenuService.queryMenusByUserId(userId);
        }
        return sysMenus;
    }
}
